/**
 * Deep Hook Script for Shumei Encryption Analysis
 * 深度Hook数美加密流程
 */

console.log("\n" + "=".repeat(80));
console.log("Deep Hook - Shumei Encryption Analysis");
console.log("=".repeat(80) + "\n");

// ============================================================================
// Part 1: Hook Native Library (libsmsdk.so)
// ============================================================================

console.log("[1] Searching for libsmsdk.so...");

var smsdk = null;
var smsdkBase = null;

// Try to find the module
try {
    smsdk = Process.findModuleByName("libsmsdk.so");
    if (smsdk) {
        smsdkBase = smsdk.base;
        console.log("[OK] Found libsmsdk.so");
        console.log("    Base Address: " + smsdkBase);
        console.log("    Size: " + smsdk.size);
        console.log("    Path: " + smsdk.path);
        
        // List all exports
        console.log("\n[*] Analyzing exports...");
        var exports = smsdk.enumerateExports();
        console.log("    Total exports: " + exports.length);
        
        var cryptoFunctions = [];
        exports.forEach(function(exp) {
            var name = exp.name.toLowerCase();
            if (name.indexOf('encrypt') !== -1 || 
                name.indexOf('aes') !== -1 ||
                name.indexOf('crypto') !== -1 ||
                name.indexOf('cipher') !== -1 ||
                name.indexOf('encode') !== -1 ||
                name.indexOf('sm_') !== -1) {
                cryptoFunctions.push(exp);
                console.log("    [!] Crypto: " + exp.name + " @ " + exp.address);
            }
        });
        
        console.log("\n[*] Found " + cryptoFunctions.length + " potential crypto functions\n");
        
        // Hook crypto functions
        cryptoFunctions.forEach(function(exp) {
            try {
                Interceptor.attach(exp.address, {
                    onEnter: function(args) {
                        console.log("\n" + "=".repeat(60));
                        console.log("[NATIVE CALL] " + exp.name);
                        console.log("=".repeat(60));
                        console.log("Args[0]: " + args[0]);
                        console.log("Args[1]: " + args[1]);
                        console.log("Args[2]: " + args[2]);
                        
                        // Try to read data
                        try {
                            if (args[0] && !args[0].isNull()) {
                                var data = Memory.readByteArray(args[0], Math.min(64, args[1].toInt32()));
                                console.log("Data[0] (64 bytes):");
                                console.log(hexdump(data, {length: 64, ansi: true}));
                            }
                        } catch(e) {
                            console.log("Cannot read args[0]: " + e);
                        }
                        
                        this.startTime = Date.now();
                    },
                    onLeave: function(retval) {
                        var elapsed = Date.now() - this.startTime;
                        console.log("Return: " + retval);
                        console.log("Time: " + elapsed + "ms");
                        console.log("=".repeat(60) + "\n");
                    }
                });
                console.log("[+] Hooked: " + exp.name);
            } catch(e) {
                console.log("[-] Failed to hook " + exp.name + ": " + e);
            }
        });
        
    } else {
        console.log("[!] libsmsdk.so not found, will search later");
    }
} catch(e) {
    console.log("[ERROR] " + e);
}

// ============================================================================
// Part 2: Hook Java Crypto APIs
// ============================================================================

Java.perform(function() {
    console.log("\n[2] Hooking Java Crypto APIs...\n");
    
    // Hook javax.crypto.Cipher
    try {
        var Cipher = Java.use("javax.crypto.Cipher");
        
        // doFinal(byte[])
        Cipher.doFinal.overload('[B').implementation = function(input) {
            console.log("\n" + "=".repeat(80));
            console.log("[JAVA CIPHER] doFinal");
            console.log("=".repeat(80));
            console.log("Algorithm: " + this.getAlgorithm());
            console.log("Provider: " + this.getProvider());
            console.log("Input length: " + input.length);
            console.log("Input (hex, first 64 bytes):");
            console.log(bytesToHex(input.slice(0, Math.min(64, input.length))));
            
            var result = this.doFinal(input);
            
            console.log("Output length: " + result.length);
            console.log("Output (hex, first 64 bytes):");
            console.log(bytesToHex(result.slice(0, Math.min(64, result.length))));
            console.log("=".repeat(80) + "\n");
            
            return result;
        };
        
        console.log("[+] Hooked Cipher.doFinal");
    } catch(e) {
        console.log("[-] Failed to hook Cipher: " + e);
    }
    
    // Hook Base64
    try {
        var Base64 = Java.use("android.util.Base64");
        
        Base64.encodeToString.overload('[B', 'int').implementation = function(input, flags) {
            var result = this.encodeToString(input, flags);
            
            console.log("\n[BASE64 ENCODE]");
            console.log("Input length: " + input.length);
            console.log("Input (hex, first 32 bytes): " + bytesToHex(input.slice(0, Math.min(32, input.length))));
            console.log("Output: " + result.substring(0, Math.min(80, result.length)) + "...");
            
            return result;
        };
        
        console.log("[+] Hooked Base64.encodeToString");
    } catch(e) {
        console.log("[-] Failed to hook Base64: " + e);
    }
    
    // Hook SecretKeySpec (shows AES key)
    try {
        var SecretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec");
        
        SecretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function(key, algorithm) {
            console.log("\n" + "!".repeat(80));
            console.log("[SECRET KEY] SecretKeySpec created");
            console.log("!".repeat(80));
            console.log("Algorithm: " + algorithm);
            console.log("Key length: " + key.length);
            console.log("Key (hex): " + bytesToHex(key));
            console.log("Key (string): " + bytesToString(key));
            console.log("!".repeat(80) + "\n");
            
            return this.$init(key, algorithm);
        };
        
        console.log("[+] Hooked SecretKeySpec");
    } catch(e) {
        console.log("[-] Failed to hook SecretKeySpec: " + e);
    }
    
    // Hook IvParameterSpec (shows IV)
    try {
        var IvParameterSpec = Java.use("javax.crypto.spec.IvParameterSpec");
        
        IvParameterSpec.$init.overload('[B').implementation = function(iv) {
            console.log("\n[IV PARAMETER] IvParameterSpec created");
            console.log("IV length: " + iv.length);
            console.log("IV (hex): " + bytesToHex(iv));
            console.log("IV (string): " + bytesToString(iv));
            
            return this.$init(iv);
        };
        
        console.log("[+] Hooked IvParameterSpec\n");
    } catch(e) {
        console.log("[-] Failed to hook IvParameterSpec: " + e);
    }
    
    console.log("[OK] Java hooks ready!\n");
});

// ============================================================================
// Helper Functions
// ============================================================================

function bytesToHex(bytes) {
    var hex = "";
    for (var i = 0; i < bytes.length; i++) {
        hex += ("0" + (bytes[i] & 0xFF).toString(16)).slice(-2);
    }
    return hex;
}

function bytesToString(bytes) {
    try {
        var str = "";
        for (var i = 0; i < bytes.length; i++) {
            var c = bytes[i] & 0xFF;
            if (c >= 32 && c <= 126) {
                str += String.fromCharCode(c);
            } else {
                str += ".";
            }
        }
        return str;
    } catch(e) {
        return "[Error: " + e + "]";
    }
}

console.log("=".repeat(80));
console.log("[READY] All hooks installed. Waiting for API calls...");
console.log("=".repeat(80) + "\n");


